package lt.liepasoft.locr.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.plaf.basic.BasicArrowButton;

import lt.liepasoft.locr.ImageManager;
import lt.liepasoft.locr.data.OcrImage;
import lt.liepasoft.locr.data.RgbImage;
import lt.liepasoft.locr.data.Symbol;
import lt.liepasoft.locr.data.SymbolImage;
import lt.liepasoft.locr.realization.FloodFillScanner;
import lt.liepasoft.locr.realization.SymbolComparator;
import lt.liepasoft.locr.utils.ImageUtils;

public class SymbolCompareDialog extends JDialog implements WindowListener {

    /**
	 * 
	 */
	private static final long serialVersionUID = -4179948744072655818L;

	public final SymbolSelectionPanel
            symbolSelectionPanel,
            symbolSelectionPanel2;
    
    private JPanel mainPanel;
    
    private CompareData compareData;    
    
    public SymbolCompareDialog() {
    	super(OcrMainFrame.getInstance(), "Symbols compare", true);
    	mainPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 15));

        compareData = new CompareData();
        symbolSelectionPanel = new SymbolSelectionPanel();
        symbolSelectionPanel2 = new SymbolSelectionPanel();
        
        ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
            	symbolSelectionPanel2.sortSymbols(new SymbolComparator(symbolSelectionPanel.getSelected()));
                compareSymbols();
                mainPanel.updateUI();
            }
        };
                        
        symbolSelectionPanel.addActionListener(listener);
        
        ActionListener listener2 = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {            	
                compareSymbols();
                mainPanel.updateUI();
            }
        };        
        symbolSelectionPanel2.addActionListener(listener2);
        
        mainPanel.add(symbolSelectionPanel);
        
        JPanel infoPanel = new JPanel(new GridLayout(4, 1, 10, 0));
        for (int i=0; i<compareData.VALUES_TITLES.length; i++) {
        	final int index = i;
        	infoPanel.add(new JLabel(){
                @Override
                public String getText() {
                    setText(compareData.VALUES_TITLES[index]+": "+(int)(compareData.values[index]*100)+"%");
                    return super.getText();
                }            
            });
        }

        infoPanel.setPreferredSize(new Dimension(150,200));
        mainPanel.add(infoPanel);
        
        mainPanel.add(symbolSelectionPanel2);
                
      
        symbolSelectionPanel2.setSymbols(new <SymbolImage> ArrayList(OcrMainFrame.getKnownSymbolsMap().values()));
                
        setContentPane(mainPanel);
        setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        //setPreferredSize(new Dimension(650, 350));
        setSize(650, 350);
        setResizable(false);
        
        addWindowListener(this);
    }            
    
    public void compareSymbols(){
        if (symbolSelectionPanel == null || symbolSelectionPanel2 == null || 
            symbolSelectionPanel.getSelected() == null || symbolSelectionPanel2.getSelected() == null) 
            return;

        SymbolImage 
                img1 = symbolSelectionPanel.getSelected(), 
                img2 = symbolSelectionPanel2.getSelected();
        
        compareData.calculate(img1, img2);
    }
        
    public class SymbolSelectionPanel extends JPanel {

        private List <SymbolImage> symbols;
        private int selectedIndex=-1;
        private JButton 
                leftButton, rightButton;        
        private SymbolDrawPanel
                    symbolDrawPanel;
        private ActionListener actionListener;
        
        public SymbolSelectionPanel() {
            super(new BorderLayout());
            //setPreferredSize(new Dimension(220,300));
            JPanel top = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
            leftButton = new BasicArrowButton(SwingConstants.WEST){
                @Override
                public boolean isEnabled() {
                    return (symbols != null);                  
                }                
            };
            leftButton.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (symbols == null) return;
                        selectedIndex -= 1;
                        if (selectedIndex < 0)
                            selectedIndex = symbols.size()-1;
                        symbolDrawPanel.setSymbolImage(getSelected());
                        
                        if (actionListener != null)
                            actionListener.actionPerformed(null);
                        
                        updateUI();
                        
                    }
                });            
            top.add(leftButton);
            JLabel label = new JLabel(){
                @Override
                public String getText() {
                    if (symbols != null){
                        setText((selectedIndex+1)+" / "+symbols.size());
                    }else{
                        setText("NO SYMBOLS");
                    }
                    return super.getText();
                }
                
            };
            top.add(label);            
            rightButton = new BasicArrowButton(SwingConstants.EAST){
                @Override
                public boolean isEnabled() {
                    return (symbols != null);                  
                }                      
            };
            rightButton.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (symbols == null) return;
                        selectedIndex += 1;
                        if (selectedIndex >= symbols.size()){
                            selectedIndex = 0;
                        }
                        symbolDrawPanel.setSymbolImage(getSelected());
                        
                        if (actionListener != null)
                            actionListener.actionPerformed(null);
                        
                        updateUI();
                    }
                });  
            top.add(rightButton);
            top.setBorder(BorderFactory.createEtchedBorder());
            
            JPanel center = new JPanel(new BorderLayout());
            symbolDrawPanel = new SymbolDrawPanel(200, 200, false);            
            center.add(symbolDrawPanel, BorderLayout.CENTER);
            center.setBorder(BorderFactory.createEtchedBorder());
            center.setPreferredSize(symbolDrawPanel.getPreferredSize());
            
            JPanel bottom = new JPanel(new GridLayout(2, 1, 10, 0));
            label = new JLabel(){
                @Override
                public String getText() {
                    if (getSelected() != null)
                        setText("All pixels: "+getSelected().npix);
                    else
                        setText("All pixels: ");
                    return super.getText();
                }                
            };            
            bottom.add(label);
            label = new JLabel(){
                @Override
                public String getText() {
                    if (getSelected() != null)
                        setText("Black pixels: "+getSelected().getBlackPixels());
                    else
                        setText("Black pixels: ");
                    return super.getText();
                }                
            };            
            bottom.add(label);
            
            this.add(top, BorderLayout.NORTH);
            this.add(center, BorderLayout.CENTER);            
            this.add(bottom, BorderLayout.SOUTH);            
        }

        public void setSymbols(List<SymbolImage> symbols) {
            this.symbols = symbols;
            if (symbols != null && !symbols.isEmpty()){                
                selectedIndex = 0;
                symbolDrawPanel.setSymbolImage(symbols.get(selectedIndex));
            } else {
                symbols = null;
            }
        }                
        
        public void addActionListener(ActionListener l){
            this.actionListener = l;
        }

        public void sortSymbols(SymbolComparator comparator){
        	Collections.sort(symbols, Collections.reverseOrder(comparator));
        	selectedIndex=0;
        	symbolDrawPanel.setSymbolImage(getSelected());
        	updateUI();
        }
        
        public SymbolImage getSelected(){            
            if (symbols != null && selectedIndex > -1 && symbols.size() > selectedIndex) 
                return symbols.get(selectedIndex);
            return null;             
        }                        
    }    

//    public List<Symbol> getSymbols(){
//        List <Symbol> symbols = new ArrayList<Symbol> ();
//        EncryptedSymbols comp = new EncryptedSymbols();
//
//        //Map <Character, SymbolImage> symbols = new ComparatorSymbols().symbols;
//        //init numbers
//        //for (String letter: letters){
//        Bounds b = new Bounds(0, 0, comp.WIDTH, comp.HEIGHT);
//        SymbolImage img;
//        for (int i=48; i<48+10; i++){
//            //Symbol s = createSymbol((char)i+"");
//            img = comp.symbols.get((char)i);
//            if (img != null){
//                Symbol s = new Symbol(b, img);
//                symbols.add(s);
//            } else {
//                System.out.println("Error: "+(char)i);
//            }
//        }
//        //init capital letters
//        for (int i=65; i<91; i++){
//            //Symbol s = createSymbol((char)i+"");
//            img = comp.symbols.get((char)i);
//            if (img != null){
//                Symbol s = new Symbol(b, img);
//                symbols.add(s);
//            } else {
//                System.out.println("Error: "+(char)i);
//            }
//        }
//        //init non-capital letters
//        for (int i=97; i<123; i++){
//            //Symbol s = createSymbol((char)i+"");
//            img = comp.symbols.get((char)i);
//            if (img != null){
//                Symbol s = new Symbol(b, img);
//                symbols.add(s);
//            } else {
//                System.out.println("Error: "+(char)i);
//            }
//        }  
//        return symbols;
//    }
    
    public Symbol createSymbol(String letter){
        ImageUtils utils = ImageUtils.getInstance();
        FloodFillScanner scanner = new FloodFillScanner();
        
        RgbImage rgb = utils.createLetterImage(letter);
        OcrImage ocr = ImageManager.createOcrImage(rgb, true);
        List <Symbol> symbols = scanner.scan(ocr, ocr.bounds);
        //System.out.println("->> "+symbols.size());
        if (symbols.size()>0){
            //System.out.println(letter+": "+symbols.get(0).getImage().getBlackPixels());
            return symbols.get(0);
        }else{            
            //System.err.println("Error with: "+letter);            
            return null;
        }
    }
    
    private class CompareData {
    	public String[] VALUES_TITLES = {"Img1 to Img2", "Img2 to Img1", "Multiplied", "Average"};
    	public float
    		img1Toimg2,
    		img2Toimg1,
    		multiply,
    		average;
    	
    	public float[] values = {0,0,0,0};
    	
    	public float[] calculate(SymbolImage img1, SymbolImage img2){
    		img1Toimg2 = img1.similarityRate(img2);
    		img2Toimg1 = img2.similarityRate(img1);
    		multiply = img1Toimg2 * img2Toimg1;  
    		average = (img1Toimg2+img2Toimg1)/2;
    		return values = getValues();
    	}
    	
    	private float[] getValues(){
    		return new float[]{img1Toimg2, img2Toimg1, multiply, average};
    	}
    }

	@Override
	public void windowActivated(WindowEvent e) {}

	@Override
	public void windowClosed(WindowEvent e) {System.out.println("close");}

	@Override
	public void windowClosing(WindowEvent e) {
		setVisible(false);		
	}
	
	@Override
	public void setVisible(boolean b) {		
		if (b) {
			if (symbolSelectionPanel.getSelected() != null){
				symbolSelectionPanel2.sortSymbols(new SymbolComparator(symbolSelectionPanel.getSelected()));
				compareSymbols();			
				mainPanel.updateUI();
			}
		}
		super.setVisible(b);
	}

	@Override
	public void windowDeactivated(WindowEvent e) {}

	@Override
	public void windowDeiconified(WindowEvent e) {}

	@Override
	public void windowIconified(WindowEvent e) {}

	@Override
	public void windowOpened(WindowEvent e) {}
      
}

